#include <iostream>
#include <vector>
#include <list>
#include <functional>
#include "String.hpp"
#include "list.h"

using namespace std;

struct Point{
    Point(int x, int y)
    :_x(x), _y(y)
    {
        cout<<_x<<" "<<_y<<endl;
    }
    Point(const Point& other) {
        cout << "拷贝构造" << endl;
    }

    int _x;
    int _y;
};

// int main(){
//     int a=1;
//     int b={2};
//     int c{3};
//     cout<<(a+b+c)<<endl;

//     Point p1(1, 1);
//     Point p2={2, 2};
//     Point p3{3, 3};

//     int *pa=new int[4]{0};
//     Point *p5=new Point{5, 5};

//     return 0;
// }

// int main(){
//     auto il = {1, 2, 3, 4};
//     cout << typeid(il).name() << endl;

//     return 0;
// }

// void func(int x){
//     cout<<"func(int x)"<<endl;
// }
// void func(int *y){
//     cout<<"func(int *y)"<<endl;
// }
// int main(){
//     //func(NULL); //预处理 宏替换后变为func(0)
//     func(nullptr);
//     return 0;
// }




// 左值引用应用场景
void func1(Mystring::string s)
{
    cout << "func1(Mystring::string s)" << endl;
}
void func2(const Mystring::string &s)
{
    cout << "func2(const Mystring::string &s)" << endl;
}

// int main()
// {
//     Mystring::string s1("hello world");
//     // func1和func2的调用我们可以看到左值引用做参数减少了拷贝，提高效率的使用场景和价值
//     // func1(s1);
//     // cout << endl;
//     // func2(s1);
//     // 两种operator+=的声明方式：
//     // 1. string operator+=(char ch);  // 传值返回，有深拷贝
//     // 2. string& operator+=(char ch); // 传引用返回，无拷贝
//     s1 += '!';
//     return 0;
// }



//右值引用应用场景
// 返回一个局部string对象
Mystring::string getString() {
    Mystring::string ret("hello");  // 局部对象
    return ret;
}
// int main(){
//     // 测试局部变量返回
//     // Mystring::string s1 = getString();
//     Mystring::string s2;
//     s2 = getString();
//     cout << "测试完成" << endl;
//     return 0;
// }


//右值引用更深入的引用场景
// int main(){
//     Mystring::string s1("helloworld");      
//     Mystring::string s2(s1);                // s1是左值 调用拷贝构造
//     Mystring::string s3(move(s1));          // move(s1)是右值 调用移动构造
//     return 0;
// }
// int main(){
//     list<Mystring::string> lt;
//     Mystring::string s1("hellowolrd");
//     lt.push_back(s1);
//     lt.push_back("1111111");
//     lt.push_back(move(s1));
//     return 0;
// }


// 完美转发
// void Fun(int &x){
//     cout << "左值引用" << endl;
// }
// void Fun(const int &x){
//     cout << "const 左值引用" << endl;
// }
// void Fun(int &&x){
//     cout << "右值引用" << endl;
// }
// void Fun(const int &&x){
//     cout << "const 右值引用" << endl;
// }

// template<typename T>
// void PerfectForward(T&& t){
//     Fun(forward<T>(t));
// }

// int main(){
//     PerfectForward(10);          // 右值

//     int a = 1;
//     PerfectForward(a);           // 左值
//     PerfectForward(move(a));     // 右值

//     const int b = 2;
//     PerfectForward(b);           // const左值
//     PerfectForward(move(b));     // const右值
//     return 0;
// }

// 完美转发应用场景
// int main(){
//     Mylist::list<Mystring::string> lt;
//     Mystring::string s1("helloworld");
//     lt.push_back(s1);
//     lt.push_back("11111111");
//     lt.push_back(move(s1));
//     return 0;
// }

// class Person{
// public:
//     // 构造函数
//     Person(const char *str = "", int a = 0)
//     :_str(str)
//     ,_a(a)
//     {}

//     // Person(const Person &P) = delete;

//     // // 拷贝构造
//     // Person(const Person& P)
//     // :_str(P._str)
//     // ,_a(P._a)
//     // {}

//     // // 拷贝赋值
//     // Person& operator=(const Person& p){
//     //     if(this!=&p){
//     //         _str = p._str;
//     //         _a = p._a;
//     //     }
//     //     return *this;
//     // }

//     // // 析构函数
//     // ~Person()
//     // {}

//     // Person(Person &&P) = delete;
//     // Person &operator=(Person &&P) = delete;

// private: 
//     Mystring::string _str;
//     int _a;
// };

// int main(){
//     Person p1("hello", 1);
//     Person p2 = p1;
//     Person p3 = move(p1);
//     Person p4;
//     p4 = move(p1);
//     return 0;
// }



// lambda表达式
// int main(){
//     vector<int> v = {5, 7, 3, 0, 8, 1, 2};
//     sort(v.begin(), v.end());                    // 默认按升序排序
//     for(auto x : v){
//         cout << x << " ";
//     }
//     cout << endl;

//     sort(v.begin(), v.end(), greater<int>());    // 如果需要降序排列，需要设置排序规则
//     for(auto x : v){
//         cout << x << " ";
//     }
//     cout << endl;
//     return 0;
// }

struct Goods
{
    string _name;      // 名字
    double _price; // 价格
    int _evaluate;     // 评价

    Goods(const char *str, double price, int evaluate)
    : _name(str), _price(price), _evaluate(evaluate)
    {}
};

// 按照价格升序进行排序
struct ComparePriceLess{
    bool operator()(const Goods& g1, const Goods& g2){
        return g1._price < g2._price;
    }
};

// 按照价格降序进行排序
struct ComparePriceGreater{
    bool operator()(const Goods& g1, const Goods& g2){
        return g1._price > g2._price;
    }
};

// 仿函数排序
// int main(){
//     vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//     sort(v.begin(), v.end(), ComparePriceLess());
//     for(auto g : v){
//         cout << g._name << " " << g._price << " " << g._evaluate << endl;
//     }
//     cout << endl;

//     sort(v.begin(), v.end(), ComparePriceGreater());
//     for(auto g : v){
//         cout << g._name << " " << g._price << " " << g._evaluate << endl;
//     }
//     cout << endl;
//     return 0;
// }

// lambda表达式排序
// int main(){
//     vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//     sort(v.begin(), v.end(), [](const Goods &g1, const Goods &g2)
//         { return g1._price < g2._price; });
//     for(auto g : v){
//         cout << g._name << " " << g._price << " " << g._evaluate << endl;
//     }
//     cout << endl;

//     sort(v.begin(), v.end(), [](const Goods &g1, const Goods &g2)
//         { return g1._price > g2._price; });
//     for(auto g : v){
//         cout << g._name << " " << g._price << " " << g._evaluate << endl;
//     }
//     cout << endl;
//     return 0;
// }



// class Person {
// public:
//      Person(int age) : _age(age) {}
    
//     void printLater() {
//         auto f = [this]() {  // 捕获this指针
//             cout << "age = " << _age << endl;
//             _age = 100;      // 可以修改成员变量
//         };
//         f();
//     }
    
// private:
//     int _age;
// };

// int main(){
//     int x = 10;
//     auto f1 = [x]() mutable
//     { x = 20; cout << x << endl; };
//     f1();
//     cout << x << endl;

//     auto f2 = [&x]() mutable
//     { x = 20; cout << x << endl; };
//     f2();
//     cout << x << endl;

//     int a = 1, b = 2, c = 3;
//     auto f3 = [=]() mutable
//     { a++; b++; c++; cout<<a<<" "<<b<<" "<<c<<" "<<endl; };
//     f3();
//     cout << a << " " << b << " " << c << " " << endl;

//     auto f4 = [&]() mutable
//     { a++; b++; c++; cout<<a<<" "<<b<<" "<<c<<" "<<endl; };
//     f4();
//     cout << a << " " << b << " " << c << " " << endl;

//     Person p(18);
//     p.printLater();  
//     return 0;
// }

// int main(){
//     int x = 10;
//     auto f = [x]() { cout << x << endl; };
//     cout << typeid(f).name() << endl;

//     auto f1 = [](){};
//     auto f2 = [](){};
//     // f1 = f2; // 错误：类型不同，不能赋值
//     return 0;
// }


// 可变模板参数
// 递归终止
// void Print(){
//     cout << "end" << endl;
// }
// // 递归展开
// template<typename T, typename... Args>
// void Print(T first, Args... args){
//     cout<<first<<" ";    // 依次是          1                        2                   3              "hello"
//     Print(args...);      // 依次是(2, 3, "hello", "world") (3, "hello", "world") ("hello", "world") ("world") ()
// }

// int main(){
//     Print(1, 2, 3, "hello", "world");
//     return 0;
// }

// 逗号表达式展开
// template<typename T>
// void PrintArg(const T& t){
//     cout << t << " ";
// }

// template<typename... Args>
// void Print(Args... args){
//     vector<int> array={(PrintArg(args), 0)...};
//     cout << endl;
// }

// int main(){
//     Print(1, 2, 3, "hello", "world");
//     return 0;
// }

// int main(){
//     cout << "======" << endl;

//     list<pair<int, Mystring::string>> lt;
//     lt.push_back({10, "hello"});
//     cout << endl;
//     lt.emplace_back(20, "world");

//     cout << "======" << endl;

//     // vector<pair<int, Mystring::string>> v;
//     // v.push_back({30, "aaaa"});
//     // cout << endl;
//     // v.emplace_back(40, "bbbb");

//     // cout << "======" << endl;

//     return 0;
// }

template<class F, class T>
T useF(F f, T x){
    static int count = 0;
    cout << "count: " << ++count << endl;
    cout << "count: " << &count << endl;
    return f(x);
}

double f(double i){
    return i / 2;
}

struct Functor{
    double operator()(double d){
        return d / 3;
    }
};

// int main(){
//     function<double(double)> f1 = f;
//     cout << useF(f1, 11.11) << endl;

//     function<double(double)> f2 = Functor();
//     cout << useF(f2, 11.11) << endl;

//     function<double(double)> f3 = [](double d){ return d / 4; };
//     cout << useF(f3, 11.11) << endl;
// }

// int main(){
//     // 函数名
//     cout << useF(f, 11.11) << endl;

//     // 函数对象（仿函数）
//     cout << useF(Functor(), 11.11) << endl;

//     // lambda表达式
//     cout << useF([](double d){ return d / 4; }, 11.11)<< endl;
//     return 0;
// }


// function包装器使用
int add(int a, int b){
    return a + b;
}
int sub(int a, int b){
    return a - b;
}
struct Add{
    double operator()(double d1, double d2){
        return d1 * d2;
    }
};
struct Fun{
    void print(int x){
        cout << x << endl;
    }
};


// bind
int main(){
    // 绑定函数名
    function<int(int, int)> f1 = bind(add, placeholders::_1, placeholders::_2);
    auto f2 = bind(add, placeholders::_1, placeholders::_2);
    cout << f1(1, 2) << endl;
    cout << f2(3, 4) << endl;

    // 绑定lambda
    function<string(string, string)> f3 = bind([](const string &str1, const string &str2)
                                             { return str1 + str2; }, placeholders::_1, placeholders::_2);
    cout << f3("hello ", "world") << endl;

    //绑定仿函数
    auto f4 = bind(Add(), placeholders::_1, placeholders::_2);
    cout << f4(1.1, 1.1) << endl;


    // 绑定部分参数
    function<int(int)> f5 = bind(add, 10, placeholders::_1);
    cout << f5(10) << endl;
    function<int(int)> f6 = bind(add, placeholders::_1, -5);
    cout << f6(10) << endl;

    // 绑定成员函数
    Fun fun;
    function<void(int)> f7 = bind(&Fun::print, &fun, placeholders::_1);                    // 直接绑定对象的指针
    f7(10);
    function<void(Fun &, int)> f8 = bind(&Fun::print, placeholders::_1, placeholders::_2); // 要求第一个参数是对象的引用
    f8(fun, 100);
    function<void(Fun *, int)> f9 = bind(&Fun::print, placeholders::_1, placeholders::_2); // 要求第一个参数是对象的指针
    f9(&fun, 200);

    // 调整参数顺序
    function<int(int, int)> f10 = bind(sub, placeholders::_1, placeholders::_2);
    cout << f10(10, 20) << endl;
    function<int(int, int)> f11 = bind(sub, placeholders::_2, placeholders::_1);
    cout << f11(10, 20) << endl;
}


// int main()
// {
//     function<int(int, int)> f1 = add;
//     cout << f1(1, 2) << endl;

//     function<void(string)> f2 = [](const string &str){ cout << str << endl; };
//     f2("hello world");

//     function<double(double, double)> f3 = Add();
//     cout << f3(1.1, 2.2) << endl;

//     Fun fun;
//     function<void(Fun&, int)> f4 = &Fun::print;
//     f4(fun, 10);
//     function<void(Fun*, int)> f5 = &Fun::print;
//     f5(&fun, 20);

//     return 0;
// }
